﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WinFormsGraphicsDevice;
using Microsoft.Xna.Framework.Graphics;
using TinyEngine.Core.Services;
using TinyEngine.Core.Renderer;
using Microsoft.Xna.Framework;
using TinyEngine.Core.Entities;

namespace TinyEngine.Editor.DefaultPlugins.TileEditor
{
    class TileDef
    {
        public Rectangle DrawRect { get; set; }
        public int TileIndex { get; set; }
    }

    public class TilesetRenderer : BasicGraphicsDeviceControl
    {
        List<TileDef> tileDefs = new List<TileDef>();
        PrimitiveBatch prim;
        int selectedIndex = -1;
        public TilesetRenderer()
        {
            Definition = new TilesetDefinition();
            
        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            if(this.Definition.Texture == null)
                return;

            this.SetDefinition(this.Definition.Texture, this.Definition.TileWidth, this.Definition.TileHeight);
            this.Invalidate();
        }
        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
        }

        public void SetDefinition(Texture2D tex, int tilewidth, int tileheight)
        {
            if(prim==null)
                prim = new PrimitiveBatch(this.GraphicsDevice);

            Definition.Texture = tex;
            Definition.TileWidth = tilewidth;
            Definition.TileHeight = tileheight;
            tileDefs.Clear();
            var xTiles = Definition.Texture.Width / Definition.TileWidth;
            var yTiles = Definition.Texture.Height / Definition.TileHeight;
            var count = xTiles * yTiles;
            var pos = new Vector2();
            for (int i = 0; i < count; i++)
            {
                var src = TileGridEntity.GetTileSourceRectangle(i, xTiles, Definition.TileWidth, Definition.TileHeight);

                tileDefs.Add(new TileDef()
                {
                    DrawRect = new Rectangle((int)pos.X, (int)pos.Y, Definition.TileWidth, Definition.TileHeight),
                    TileIndex = i
                });

                pos.X += Definition.TileWidth;
                if (pos.X + Definition.TileWidth > this.ClientSize.Width)
                {
                    pos.X = 0;
                    pos.Y += Definition.TileHeight;
                }
            }
        }
        protected override void Draw()
        {
            base.Draw();

            var sp = ServiceManager.GetService<SpriteBatchService>();
            
            if (Definition.Texture != null)
            {
                sp.Batch.Begin();

                DrawTiles(sp.Batch);
                
                sp.Batch.End();

                if (selectedIndex != -1 && prim!=null)
                {
                    prim.SetProjection(this.ClientSize.Width, this.ClientSize.Height);
                    
                    var it = tileDefs[selectedIndex];
                    prim.DrawBox(it.DrawRect, Color.White);
                }
            }
        }

        protected override void OnMouseClick(System.Windows.Forms.MouseEventArgs e)
        {
            var posX = e.X;
            var posY = e.Y;
            
            foreach (var item in tileDefs)
            {
                if (item.DrawRect.Contains(new Point(posX, posY)))
                {
                    selectedIndex = item.TileIndex;
                    this.Invalidate();
                    break;
                }
            }
            base.OnMouseClick(e);
        }

        private void DrawTiles(SpriteBatch spriteBatch)
        {
            var xTiles = Definition.Texture.Width / Definition.TileWidth;
            var yTiles = Definition.Texture.Height / Definition.TileHeight;
            var count = xTiles * yTiles;
            var pos = new Vector2();
            for (int i = 0; i < count; i++)
            {
                var src = TileGridEntity.GetTileSourceRectangle(i, xTiles, Definition.TileWidth, Definition.TileHeight);
                spriteBatch.Draw(
                    Definition.Texture,
                    pos,
                    src,
                    Color.White);

                pos.X += Definition.TileWidth;
                if (pos.X + Definition.TileWidth > this.Width)
                {
                    pos.X = 0;
                    pos.Y += Definition.TileHeight;
                }
            }
            
        }

        public TilesetDefinition Definition { get; private set; }
    }
    public class TilesetDefinition
    {
        public Texture2D Texture { get; set; }
        public int TileWidth { get; set; }
        public int TileHeight { get; set; }
    }
}
